from visa import instrument
from array import array as _array
from cmath import *
from numpy import array, linspace, logspace, pi, log, sin, log10, sqrt, vstack, hstack, transpose
from scipy.interpolate import splprep, splrep, splev
from pychartdir import *
import os,re
import time
j= complex(0,1)


start_freq = 0.5  #MHz  , min: 0.3, max:3000 for 8753C NA
end_freq = 20 # MHz
points = 401 # number of points

na = instrument("GPIB1::16")  ## timeout 1 second, an Agilent 8753C Network Analyzer

def reset():
    na.write("pres;") # preset

    na.write("chan1;s11;logm;cont;") ## channel 1, s11, log magnitude

    na.write("star  %fMHz;"%start_freq)
    na.write("stop  %fMHz;"%end_freq)
    na.write("poin %d"%points)
    time.sleep(1)


def readCali():
    calarray = []
    for ca,num in [("caliresp?;",1), ("calirai?;",2), ## response, response and isolation
               ("califul2?;",12), ## full 2-port
               ("calis111?;",3), ## 1-port at port 1
               ("calis221?;",3), ## 1-port at port 2
               ]:
        resp = na.ask(ca)
        if not '0' in resp:
            print 'fount %s calibration data'%ca
            for i in range(num):
                calarray.append(na.ask("outpcalc%02d;"%(i+1)))
                print 'cal array[%d] is stored'%(i+1)
            return calarray
    print 'no active calibration found'

def writeCali(caldata):
    ## assuming it's full 2 port data array, len(caldata)==12
    na.write("star  %fMHz;"%start_freq)
    na.write("stop  %fMHz;"%end_freq)
    na.write("poin %d"%points)    
    na.write("califul2;")
    for i in range(1,13):
        print "writing array %d"%i
        na.write("form1;inpucalc%02d;"%i)
        na.write(caldata[i-1])
    na.write("savc;")
    na.write("cont;")
    print "done"

def writeCaliToFile(caldata):
    for i in range(len(caldata)):
        fp = open("cal12_%d.bin"%i, 'wb')
        fp.write(caldata[i])
        fp.close()

def readCaliFromFile():
    cad = []
    for i in range(12):
        fp = open("cal12_%d.bin"%i, 'rb')
        cad.append(fp.read())
        fp.close()
    return cad

def cali2Port():
    ## not working... sigh...
    na.write("calk35mm;menuoff;cles;ese 64;")
    na.write("califul2;")

    na.write("refl;")
    print "connect OPEN at port 1...",
    raw_input()
    na.ask("class11a;opc?;stanb;")
    print "connect SHORT at port 1...",
    raw_input()
    na.ask("class11b;opc?;stanb;")
    print "connect LOAD at port 1...",
    raw_input()
    na.ask("opc?;class11c;")

    print "connect OPEN at port 2...",
    raw_input()
    na.ask("class22a;opc?;stana;")
    print "connect SHORT at port 1...",
    raw_input()
    na.ask("class22b;opc?;stana;")
    print "connect LOAD at port 1...",
    raw_input()
    na.ask("opc?;class22c;")
    na.write("refd;")
    print "computing reflection calibration coefficients..."

    na.write("tran;")
    print "connect THRU port1 to port2...",
    raw_input()
    print "measuring forward transmission..."
    na.ask("opc?;fwdt;")
    na.ask("opc?;fwdm;")
    print "measuring reverse transmission..."
    na.ask("opc?;revt;")
    na.ask("opc?;revm;")
    na.write("trad;")

    print 'skip isolation cal ? (Y or N)',
    ans = raw_input().lower()
    if 'y' in ans:
        na.write("omii;")
        print "isolation test is skipped..."
    else:
        print 'isolate test ports'
        raw_input()
        na.write("isol;averfact10;averdon;")
        print 'measuring reverse isolation'
        na.ask("opc?;revi;")
        print 'measuring forward isolation'
        na.ask("opc?;fwdi;")
    na.write("isod;averooff;")
    na.write("pg;")
    print "computing calibration coefficients...",
    na.ask("opc?;sav2;")
    print "Done full 2-ports cal."
    na.write("menuon;")

from Coil_sp_to_RLM import j,pol
    
def s11():
    na.write("chan1;s11;logm;sing;form5;hold")
    data = na.ask("outpform;")
    logdb = array(_array('f',data[4:]))
    na.write("phas")
    data = na.ask("outpform;")
    phase = array(_array('f',data[4:]))
    return pol(10**(logdb/20),phase)[::2]

def s12():
    na.write("chan1;s12;logm;sing;form5;hold")
    data = na.ask("outpform;")
    logdb = array(_array('f',data[4:]))
    na.write("phas")
    data = na.ask("outpform;")
    phase = array(_array('f',data[4:]))
    return pol(10**(logdb/20),phase)[::2]

def s21():
    na.write("chan1;s21;logm;sing;form5;hold")
    data = na.ask("outpform;")
    logdb = array(_array('f',data[4:]))
    na.write("phas")
    data = na.ask("outpform;")
    phase = array(_array('f',data[4:]))
    return pol(10**(logdb/20),phase)[::2]

def s22():
    na.write("chan1;s22;logm;sing;form5;hold")
    data = na.ask("outpform;")
    logdb = array(_array('f',data[4:]))
    na.write("phas")
    data = na.ask("outpform;")
    phase = array(_array('f',data[4:]))
    return pol(10**(logdb/20),phase)[::2]

def s11ri():
    na.write("chan1;s11;real;sing;form5;hold")
    data = na.ask("outpform;")
    real = array(_array('f',data[4:]))
    na.write("imag")
    data = na.ask("outpform;")
    imag = array(_array('f',data[4:]))
    na.write("logm;")
    data = na.ask("outpform;")
    logdb = array(_array('f',data[4:]))
    na.write("phas")
    data = na.ask("outpform;")
    phase = array(_array('f',data[4:]))    
    return real,imag,logdb,phase

def genS2p(filename=None):
    if filename==None:
        print "enter the S2P file name:",
        filename = raw_input().strip()
    a,b,c,d = s11(),s12(),s21(),s22()
    
    fp = open(filename, 'wb')
    fp.write("! generated from HP/Agilent 8753C\n")
    fp.write("# MHz xxxx 50.0\n")
    for i in range(len(a)):
        freq = start_freq + (end_freq-start_freq)*i*1.0/points
        fp.write("%f %f %f %f %f %f %f %f %f\n"%(freq, a[i].real, a[i].imag,
                                                b[i].real, b[i].imag,
                                                c[i].real, c[i].imag,
                                                d[i].real, d[i].imag))
    fp.close()
    na.write("s11;smic;cont;")
    return a,b,c,d
    
def setCali():
    na.write("pres;") # preset
    na.write("chan1;s11;logm;cont;") ## channel 1, s11, log magnitude
    na.write("star  %fMHz;"%start_freq)
    na.write("stop  %fMHz;"%end_freq)
    na.write("poin %d"%points)
    ca = readCaliFromFile()
    writeCali(ca)
    print 'calibration restored.'
    

if __name__ == '__main__':
    print "reset ? Y/N",
    ans = raw_input().lower()
    if 'y' in ans:
        reset()



##na.write("sing;form4;hold;outpform;")
##test4 = na.read()
##print test4, "\n^^^^^ form4 ^^^^^"
##
##na.write("form4;outpform;")
##test4 = na.read()
##print test4
##print "^^^^^ form4 again ^^^^^"
##
##na.write("form1;outpform;")
##test1 = na.read()
##print repr(test1)
##print "^^^^^ form1(internal) ^^^^^"
##
##na.write("form2;outpform;")
##test2 = na.read()
##print _array('f',test2[4:][::-1])[::-1]
##print "^^^^^ form2 ^^^^^"
##
##na.write("form3;outpform;")
##test3 = na.read()
##print _array('d',test3[4:][::-1])[::-1]
##print "^^^^^ form3 ^^^^^"
##
##na.write("form5;outpform;")
##test5 = na.read()
##print _array('f',test5[4:])
##print "^^^^^ form5 ^^^^^"
##
##na.write("outpleas;")
##test1 = na.read()
##print repr(test1)
##print "^^^^^ outpleas ^^^^^"
##na.write("cont")
